
;; -------- color-rg --------
(use-package color-rg
  :load-path "lazycat-bucket/color-rg"
  :bind
  (("C-M-d" . 'color-rg-search-symbol-in-project)
   ("C-c d" . 'color-rg-search-input-in-project)
   ("C-c D" . 'color-rg-search-input-in-current-file)))

;; -------- ido --------
(use-package ido
  :config
  (setq ido-create-new-buffer 'always)
  (setq ido-enable-flex-matching t)
  (setq ido-enable-last-directory-history nil)
  (setq ido-everywhere t)
  (setq ido-use-filename-at-point 'guess)
  (setq ido-use-virtual-buffers t)
  (ido-mode 1))

;; -------- (& ivy counsel projectile swiper) --------
(use-package counsel
  :defer t
  :diminish counsel-mode
  :init
  (setq enable-recursive-minibuffers t) ;; Allow commands in minibuffers
  :config
  (counsel-mode 1)
  ;; (defalias 'execute-extended-command 'counsel-M-x)
  :bind
  (("<f1> c" . 'describe-char)
   ("<f1> f" . 'counsel-describe-function)
   ("<f1> v" . 'counsel-describe-variable)
   ("<f1> l" . 'counsel-find-library)
   ("<f1> i" . 'counsel-info-lookup-symbol)
   ("<f1> u" . 'counsel-unicode-char)
   ("C-x C-f" . 'counsel-find-file)
   ("M-y" . 'counsel-yank-pop)
   :map counsel-mode-map
   ([remap swiper] . counsel-grep-or-swiper)
   ([remap dired] . counsel-dired)
   ([remap set-variable] . counsel-set-variable)
   ([remap insert-char] . counsel-unicode-char)
   ([remap recentf-open-files] . counsel-recentf)
   :map ivy-minibuffer-map
   ("M-y" . 'ivy-next-line)))

(use-package projectile
  :defer t
  :diminish projectile-mode
  :init
  (setq projectile-completion-system 'ivy)
  :bind
  (("C-c f" . 'projectile-find-file))
  :config
  (projectile-mode)
  (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))

;; ivy integration for projectile
(use-package counsel-projectile
  :defer t
  :config
  (counsel-projectile-mode 1))

(use-package all-the-icons-ivy-rich
  :if window-system
  :init
  (all-the-icons-ivy-rich-mode 1))

(use-package ivy-rich
  :defer t
  :init
  (ivy-rich-mode 1))

(use-package ivy
  :defer t
  :diminish
  :hook
  ((ivy-mode) . counsel-mode)
  :config
  (setq ivy-use-virtual-buffers t ;; recentf
	    ivy-count-format "(%d/%d) "
	    enable-recursive-minibuffers t
	    ivy-display-style 'fancy
	    ivy-ignore-buffers '("^\\*autoconnect-NOX"
			                 "^\\*NOX "
			                 "^\\*flycheck-posframe-buffer")
	    ivy-height 10)
  :bind
  (("C-x b" . 'ivy-switch-buffer)))

(use-package swiper
  :defer t
  :bind
  (("C-s" . 'swiper-isearch)))

;; enhance fuzzy matching
;; (use-package flx)

;; (use-package ivy-fuz
;;   :ensure t
;;   :demand t
;;   :after ivy
;;   :custom
;;   (ivy-sort-matches-functions-alist '((t . ivy-fuz-sort-fn)))
;;   (ivy-re-builders-alist '((t . ivy-fuz-regex-fuzzy)))
;;   :config
;;   (add-to-list 'ivy-highlight-functions-alist '(ivy-fuz-regex-fuzzy . ivy-fuz-highlight-fn))
;;   (setq ivy-fuz-sort-limit 5000))

;; enhance M-x
(use-package amx
  :init
  (setq amx-history-length 20)
  :hook
  ((ivy-mode) . amx-mode))

;; Better sorting and filtering
(use-package prescient
  :defer t
  :commands prescient-persist-mode
  :init
  (setq prescient-filter-method '(literal regexp initialism fuzzy))
  (prescient-persist-mode 1))

(use-package ivy-prescient
  :defer t
  :commands ivy-prescient-re-builder
  :custom-face
  (ivy-minibuffer-match-face-1 ((t (:inherit font-lock-doc-face :foreground nil))))
  :init
  (defun ivy-prescient-non-fuzzy (str)
    "Generate an Ivy-formatted non-fuzzy regexp list for the given STR.
This is for use in `ivy-re-builders-alist'."
    (let ((prescient-filter-method '(literal regexp)))
      (ivy-prescient-re-builder str)))
  (setq ivy-prescient-retain-classic-highlighting t
	    ivy-re-builders-alist
	    '((counsel-ag . ivy-prescient-non-fuzzy)
	      (counsel-rg . ivy-prescient-non-fuzzy)
	      (counsel-pt . ivy-prescient-non-fuzzy)
	      (counsel-grep . ivy-prescient-non-fuzzy)
	      (counsel-imenu . ivy-prescient-non-fuzzy)
	      (counsel-yank-pop . ivy-prescient-non-fuzzy)
	      (swiper . ivy-prescient-non-fuzzy)
	      (swiper-isearch . ivy-prescient-non-fuzzy)
	      (swiper-all . ivy-prescient-non-fuzzy)
	      (lsp-ivy-workspace-symbol . ivy-prescient-non-fuzzy)
	      (lsp-ivy-global-workspace-symbol . ivy-prescient-non-fuzzy)
	      (insert-char . ivy-prescient-non-fuzzy)
	      (counsel-unicode-char . ivy-prescient-non-fuzzy)
	      (t . ivy-prescient-re-builder))
	    ivy-prescient-sort-commands
	    '(:not swiper swiper-isearch ivy-switch-buffer
	           lsp-ivy-workspace-symbol ivy-resume ivy--restore-session
	           counsel-grep counsel-git-grep counsel-rg counsel-ag
	           counsel-ack counsel-fzf counsel-pt counsel-imenu
	           counsel-yank-pop counsel-recentf counsel-buffer-or-recentf))
  (ivy-prescient-mode 1))

;; ;; -------- dumb-jump --------
;; (use-package dumb-jump
;;   :ensure t
;;   :config
;;   (dumb-jump-mode)
;;   (setq dumb-jump-selector 'ivy)
;;   :bind
;;   (("M-g o" . dumb-jump-go-other-window)
;;    ("M-g j" . dumb-jump-go)
;;    ("M-g b" . dumb-jump-back)
;;    ("M-g i" . dumb-jump-go-prompt)
;;    ("M-g x" . dumb-jump-go-prefer-external)
;;    ("M-g z" . dumb-jump-go-prefer-external-other-window)))

;; ;; -------- (ivy-)posframe --------
;; (use-package ivy-posframe
;;   :config
;;   (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display)))
;;   (setq ivy-fixed-height-minibuffer nil
;;         ;; ivy-posframe-height-alist '((swiper . 20)
;;         ;;                             (t . 30))
;;         ivy-posframe-parameters
;;         `((min-width . ,(* (frame-width) 0.8))
;;           (min-height . ,ivy-height)
;;           (internal-border-width . 3))
;;         ivy-display-functions-alist
;;         '((swiper . ivy-posframe-display-at-point)
;;           (complete-symbol . ivy-posframe-display-at-point)
;;           (completion-at-point . ivy-posframe-display-at-point)
;;           (counsel-M-x . ivy-posframe-display-at-window-bottom-left)
;;           (ivy-completion-in-region . ivy-posframe-display-at-point)
;;           (t . ivy-posframe-display)))
;;   (ivy-posframe-enable))
;; Show ivy frame using posframe

(use-package ivy-posframe
  :defer t
  :diminish ivy-posframe-mode
  :if window-system
  :custom
  (ivy-display-function #'ivy-posframe-display-at-frame-center)
  ;; (ivy-posframe-width 130)
  ;; (ivy-posframe-height 11)
  (ivy-posframe-height-alist '((counsel-find-file . 20)
                               (counsel-M-x       . 20)
                               (ivy-switch-buffer . 20)
                               (swiper-isearch    . 20)))
  (ivy-posframe-parameters
   '((left-fringe  . 5)
     (right-fringe . 5)))
  ;; :custom-face
  ;; (ivy-posframe ((t (:background "#282a36"))))
  ;; (ivy-posframe-border ((t (:background "#6272a4"))))
  ;; (ivy-posframe-cursor ((t (:background "#61bfff"))))
  :hook
  ((after-init) . ivy-posframe-mode)
  (ivy-mode . ivy-posframe-enable))

(provide '+search)
